package com.sc.nft.admin.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.sc.nft.admin.request.*;
import com.sc.nft.admin.vo.BoxProductVO;
import com.sc.nft.annotation.SysMemberLogin;
import com.sc.nft.dao.*;
import com.sc.nft.entity.*;
import com.sc.nft.entity.dto.AddBoxCollectionItemDTO;
import com.sc.nft.entity.dto.AddBoxEquityItemDTO;
import com.sc.nft.entity.dto.BoxPoolModificationSort;
import com.sc.nft.entity.vo.*;
import com.sc.nft.enums.CollectionChainStatusEnum;
import com.sc.nft.enums.CollectionOriginalTypeEnum;
import com.sc.nft.enums.CommodityType;
import com.sc.nft.exception.GlobalRunTimeException;
import com.sc.nft.service.BoxEquityService;
import com.sc.nft.service.BoxProductService;
import com.sc.nft.service.BoxTakeConversionConditionService;
import com.sc.nft.sup.PageResult;
import com.sc.nft.sup.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Slf4j
@RequiredArgsConstructor
@RestController
@RequestMapping("/admin/box")
@Api(tags = "后台盲盒模块")
public class BoxProductAdminController {

    private final BoxProductService boxProductService;

    private final BoxTakePoolDao boxTakePoolDao;

    private final EquityPropsDao equityPropsDao;

    private final DigitalCollectionProductInfoDao digitalCollectionProductInfoDao;

    private final DigitalCollectionDao digitalCollectionDao;

    private final BoxEquityService boxEquityService;

    private final BoxTakeConversionConditionService boxTakeConversionConditionService;

    private final UserCreatorInfoDao userCreatorInfoDao;

    @PostMapping(value = "/addBox", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "添加盲盒", notes = "添加盲盒", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public Result addBox(@Valid @RequestBody AddBoxProductRequest request) {
        if (ObjectUtil.isNotNull(boxProductService.getByTitle(request.getFirstTitle()))) {
            return Result.fail("盲盒标题已存在");
        }
        BoxProduct boxProduct = BeanUtil.toBean(request, BoxProduct.class);
        boxProduct.setStatus(Boolean.FALSE);
        boxProduct.insert();
        return Result.success();
    }

    @PostMapping(value = "/editBox", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "编辑盲盒", notes = "编辑盲盒", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public Result editBox(@Valid @RequestBody EditBoxProductRequest request) {
        BoxProduct boxProduct = boxProductService.getById(request.getId());
        if (ObjectUtil.isNull(boxProduct)) {
            return Result.fail("未找到盲盒");
        }
        if (boxProduct.getStatus()) {
            return Result.fail("盲盒已上架不能编辑");
        }
        if (boxProduct.getBoxCount() != null && boxProduct.getBoxCount().intValue() < 1) {
            return Result.fail("数量不正确");
        }
        BoxProduct boxProduct1 = BeanUtil.toBean(request, BoxProduct.class);
        boxProductService.editBox(boxProduct1);
        return Result.success();
    }

    @PostMapping(value = "/pageBox", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "盲盒列表", notes = "盲盒列表", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public PageResult<BoxProductVO> editCollection(@Valid @RequestBody PageBoxProductRequest request) {
        Page p = boxProductService.page(request.getFirstTitle(), request.getStatus(), request.getPageNo(), request.getPageSize());
        return PageResult.success(p, BoxProductVO.class);
    }

    @PostMapping(value = "/itemList", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "盲盒子项列表", notes = "盲盒子项列表", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public Result<List<BoxItemVO>> editCollection(@Valid @RequestBody IdRequest request) {
        return Result.success(boxProductService.getBoxItem(request.getId()));
    }

    @PostMapping(value = "/simpleList", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "盲盒简单列表", notes = "盲盒简单列表", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public Result<List<CollectionSimpleVO>> simpleList(@RequestBody ListDigitalCollectionRequest request) {
        return Result.successColl(boxProductService.getCollectionSimpleVO(request.getFirstTitle()), CollectionSimpleVO.class);
    }

    @PostMapping(value = "/onStatus", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "盲盒上架", notes = "盲盒上架", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public Result onStatus(@RequestBody IdRequest request) {
        BoxProduct boxProduct = boxProductService.getById(request.getId());
        if (ObjectUtil.isNull(boxProduct)) {
            return Result.fail("未找到盲盒");
        }
        if (boxProduct.getStatus()) {
            return Result.fail("盲盒已上架不能编辑");
        }
        List<BoxItemVO> itemVOS = boxProductService.getBoxItem(boxProduct.getId());
        if (itemVOS.stream().mapToInt(BoxItemVO::getSumCount).sum() != boxProduct.getBoxCount().intValue()) {
            return Result.fail("盲盒商品子项不正确");
        }
        boxProduct.setStatus(true);
        boxProduct.updateById();
        return Result.success();
    }

    @PostMapping(value = "/addItem", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "盲盒添加藏品", notes = "盲盒添加藏品", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public Result addItem(@Valid @RequestBody AddBoxProductItemRequest request) {
        BoxProduct boxProduct = boxProductService.getById(request.getId());
        if (ObjectUtil.isNull(boxProduct)) {
            return Result.fail("盲盒不存在");
        }
        if (boxProduct.getStatus()) {
            return Result.fail("盲盒已上架不可修改");
        }
        int sumCount = request.getBoxCollections().stream().mapToInt(BoxCollection::getCount).sum();

        if (sumCount != boxProduct.getBoxCount()) {
            return Result.fail("总数不匹配");
        }
        List<BoxItem> boxItems = Lists.newArrayList();
        request.getBoxCollections().forEach(boxCollection -> {
            Long collectionId = boxCollection.getCollectionId();
            if (boxCollection.getCollectionId() >= 144L) {
                DigitalCollection collection = digitalCollectionDao.getById(collectionId);
                if (collection.getChainStatus() != CollectionChainStatusEnum.CHAIN_COMPLETED) {
                    throw new GlobalRunTimeException(collection.getFirstTitle() + "藏品未上链");
                }

                Assert.isTrue(collection.getOriginalType() == CollectionOriginalTypeEnum.MATE_UNIVERSE, () -> new GlobalRunTimeException("玛特钱包的藏品不能添加到盲盒"));
            }

            BoxItem boxItem = new BoxItem();
            boxItem.setBoxId(boxProduct.getId());
            boxItem.setCollectionId(boxCollection.getCollectionId());
            boxItem.setSumCount(boxCollection.getCount());
            boxItem.setShowProbability(boxItem.getSumCount() * 100 / boxProduct.getBoxCount() + "%");
            boxItems.add(boxItem);
        });
        boxProductService.addItem(boxItems, boxProduct.getId());
        return Result.success();
    }

    @PostMapping(value = "/addBoxPool", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "添加盲盒抽奖池", notes = "添加盲盒抽奖池", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public Result addBoxPool(@Valid @RequestBody AddBoxPoolRequest request) {
        DigitalCollectionProductInfo blindBoxDetails = digitalCollectionProductInfoDao.getAllBlindBoxDetails(request.getProductBoxId(), 0);
        if (ObjectUtil.isNull(blindBoxDetails)) {
            return Result.fail("盲盒商品不存在");
        }
        BoxProduct boxProduct = boxProductService.getById(blindBoxDetails.getRelationId());
        if (ObjectUtil.isNull(boxProduct)) {
            return Result.fail("未找到盲盒");
        }
        if (!boxProduct.getStatus()) {
            return Result.fail("盲盒未上架不可添加");
        }
        Assert.isTrue(
                blindBoxDetails.getCommodityType() == CommodityType.EXCHANGE_COLLECTION,
                () -> new GlobalRunTimeException("只有兑换商品才能添加"));
        boxTakeConversionConditionService.addBoxCondition(true, null, 1, blindBoxDetails.getId(), request.getUpperLimit(), request.getAddBoxConditionCollectionDTO(), request.getAddBoxCondition(), request.getConvertScenario(), request.getDaoId(),null);
        return Result.success();
    }

//    @PostMapping(value = "/editBoxPool", produces = MediaType.APPLICATION_JSON_VALUE)
//    @ApiOperation(value = "编辑抽奖池盲盒", notes = "编辑抽奖池盲盒", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
//    @SysMemberLogin
//    public Result editBoxPool(@Valid @RequestBody EditBoxPoolRequest request) {
//        BoxTakePool boxTakePool = boxTakePoolDao.getById(request.getId());
//        if (ObjectUtil.isNull(boxTakePool)) {
//            return Result.fail("未找到抽奖池盲盒");
//        }
//        EquityProps equityProps = equityPropsDao.getById(request.getPropsId());
//
//        if (ObjectUtil.isNull(equityProps)) {
//            return Result.fail("未找到虚拟道具");
//        }
//        if (equityProps.getTypeClassify() != EquityPropsTypeEnum.VOUCHER) {
//            return Result.fail("虚拟道具类型不正确");
//        }
//        boxTakePool.setPropsId(equityProps.getId());
//        boxTakePool.setPropsName(equityProps.getFirstTitle());
//        boxTakePool.setCostQuantity(request.getCostQuantity());
//        boxTakePool.updateById();
//        return Result.success();
//    }

//    @PostMapping(value = "/removeBoxPool", produces = MediaType.APPLICATION_JSON_VALUE)
//    @ApiOperation(value = "删除盲盒抽奖池", notes = "删除盲盒抽奖池", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
//    @SysMemberLogin
//    @Deprecated
//    public Result removeBoxPool(@Valid @RequestBody IdRequest request) {
//        BoxTakePool boxTakePool = boxTakePoolDao.getById(request.getId());
//        if (ObjectUtil.isNull(boxTakePool)) {
//            return Result.fail("未找到抽奖池盲盒");
//        }
//        boxTakePool.deleteById();
//        return Result.success();
//    }

    @PostMapping(value = "/boxPoolList", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "盲盒抽奖池列表", notes = "盲盒抽奖池列表", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public PageResult<BoxPoolVO> boxPoolList(@RequestBody @Valid BoxPoolSearchRequest request) {
        Page<BoxPoolVO> boxPoolVOPage = boxTakePoolDao.boxPoolPage(null, request.getBoxName(), request.getConvertScenario(), request.getDaoId(), request.getPageNo(), request.getPageSize());
        boxPoolVOPage.getRecords().forEach(boxPoolVO -> {
            BoxTakeConversionConditionCombination boxTakeConversionConditionCombination = boxTakeConversionConditionService.boxTakeConversionConditionCombination(boxPoolVO.getId());
            boxPoolVO.setConditionName(boxTakeConversionConditionCombination.getConditionName());
            boxPoolVO.setCollectionName(boxTakeConversionConditionCombination.getCollectionName());
            if (Objects.nonNull(boxPoolVO.getDaoId())) {
                GetDaoByIdVO getDaoByIdVO = userCreatorInfoDao.getDaoById(boxPoolVO.getDaoId());
                if (Objects.nonNull(getDaoByIdVO)) {
                    boxPoolVO.setDaoName(getDaoByIdVO.getDaoName());
                }
            }
        });
        return PageResult.success(boxPoolVOPage);
    }

    @PostMapping(value = "/boxPoolStatus", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "盲盒抽奖池上下架", notes = "盲盒抽奖池上下架", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public Result boxPoolStatus(@Valid @RequestBody BoxPoolStatusRequest request) {
        BoxTakePool boxTakePool = boxTakePoolDao.getById(request.getId());
        if (ObjectUtil.isNull(boxTakePool)) {
            return Result.fail("未找到抽奖池盲盒");
        }
        boxTakePool.setStatus(request.getStatus());
        boxTakePool.updateById();
        return Result.success();
    }


    @PostMapping(value = "/sortModification", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "兑换盲盒or兑换藏品修改排序", notes = "兑换盲盒or兑换藏品修改排序", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public Result sortModification(@Valid @RequestBody BoxPoolModificationSort boxPoolModificationSort) {
        boxTakePoolDao.sortModification(boxPoolModificationSort.getId(), boxPoolModificationSort.getRanking());
        return Result.success();
    }

    @PostMapping(value = "/editBoxCollectionEquity", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "修改盲盒藏品奖励", notes = "修改盲盒藏品奖励", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public Result editBoxCollectionEquity(@Valid @RequestBody AddBoxEquityRequest request) {
        BoxProduct boxProduct = boxProductService.getById(request.getBoxId());
//        if (boxProduct.getStatus()) {
//            throw new GlobalRunTimeException("已上架的盲盒无法修改！");
//        }
        List<AddBoxCollectionItemDTO> boxItemList = request.getBoxItemList();
        boxItemList.forEach(b -> {
            List<AddBoxEquityItemDTO> equityItemList = b.getEquityItemList();
            List<BoxEquity> list = Lists.newArrayList();
            if (CollectionUtil.isNotEmpty(equityItemList)) {
                list = equityItemList.stream().map(e -> BeanUtil.copyProperties(e, BoxEquity.class)).collect(Collectors.toList());
            }
            boxEquityService.addBoxEquityList(request.getBoxId(), b.getBoxItemId(), list);
        });
        return Result.success();
    }

    @PostMapping(value = "/getCollectionEquityList", produces = MediaType.APPLICATION_JSON_VALUE)
    @ApiOperation(value = "获取盲盒奖励列表", notes = "获取盲盒奖励列表", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_VALUE)
    @SysMemberLogin
    public Result<List<BoxCollectionEquityVO>> getCollectionEquityList(@Valid @RequestBody IdRequest request) {
        BoxProduct boxProduct = boxProductService.getById(request.getId());
        if (ObjectUtil.isNull(boxProduct)) {
            return Result.fail("盲盒不存在！");
        }
        List<BoxCollectionEquityVO> result = boxEquityService.getBoxEquity(request.getId());
        return Result.success(result);

    }
}
